package com.jh.user.business.impl;

import cn.jh.common.exception.ServiceException;
import cn.jh.common.utils.DateUtil;
import com.jh.user.business.ChannelRateBusiness;
import com.jh.user.business.UserBalanceBusiness;
import com.jh.user.pojo.*;
import com.jh.user.repository.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class UserBalanceBusinessImpl implements UserBalanceBusiness{
	private static final Logger log = LoggerFactory.getLogger(UserBalanceBusinessImpl.class);


	@Autowired
	private UserAccountRepository accountRepository;

	@Autowired
	private UserBalanceRepository userBalanceRepository;

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private UserRebateHistoryRepository  userRebateHistoryRepository;


	@Autowired
	private UserCoinRepository UserCoinRepository;

	@Autowired
	private EntityManager em;

	@Autowired
	private UserAccountFreezeHistoryRepository userAccountFreezeHistoryRepository;


	@Autowired
	private UserRebateFreezeHistoryRepository  userRebateFreezeHistoryRepository;

	@Autowired
	private ChannelRateBusiness channelRateBusiness;

	/**查询用户的账户信息*/
	public UserAccount queryUserAccountByUserid(long userid){
		UserAccount userAccount = accountRepository.findUserAccountByUserid(userid);
		if (userAccount == null) {
			return UserAccount.initUserAccount(userid);
		}
		return userAccount;
	}

	/**锁定用户的账户信息*/
	@Transactional
	public UserAccount lockUserAccount(long userid){
		return accountRepository.findUserAccountByUseridLock(userid);
	}

	@Override
	public Page<UserBalanceHistory> queryUserBalHistoryByUserid(long userid,
																Pageable pageAble) {
		return userBalanceRepository.findBalHistoryByUserid(userid, pageAble);
	}

	@Transactional
	@Override
	public UserAccount saveUserAccount(UserAccount userAccount) {
		UserAccount result = accountRepository.save(userAccount);
		em.flush();
		return result;
	}

	@Transactional
	@Override
	public UserBalanceHistory saveUserBalanceHistory(
			UserBalanceHistory balHistory) {
		UserBalanceHistory result = userBalanceRepository.save(balHistory);
		em.flush();
		return result;
	}


	/**addorsub  0 表示冻结   1表示解冻 */
	@Transactional
	@Override
	public UserAccount freezeUserAccount(UserAccount userAccount, BigDecimal amount, String addorsub, String ordercode) throws Exception{

		UserAccount olduserAccount = accountRepository.findUserAccountByUseridLock(userAccount.getUserId());

		/**账户先减去钱， 然后冻结账户增加钱*/
		if(addorsub.equalsIgnoreCase("0")){

			BigDecimal curBal = userAccount.getBalance().subtract(amount);
			BigDecimal freezeBal = userAccount.getFreezeBalance().add(amount);

			olduserAccount.setFreezeBalance(freezeBal);
			olduserAccount.setBalance(curBal);

		}else{

			BigDecimal curBal = userAccount.getBalance().add(amount);
			BigDecimal freezeBal = userAccount.getFreezeBalance().subtract(amount);


			if(freezeBal.compareTo(BigDecimal.ZERO) < 0){
				throw new Exception("不能多解冻金额");
			}

			olduserAccount.setFreezeBalance(freezeBal);
			olduserAccount.setBalance(curBal);

		}
		UserAccount newAcct = accountRepository.save(olduserAccount);

		UserAccountFreezeHistory  userAccountHistory = new  UserAccountFreezeHistory();
		userAccountHistory.setAddOrSub(addorsub);
		userAccountHistory.setAmount(amount);
		userAccountHistory.setCreateTime(new Date());
		userAccountHistory.setOrderCode(ordercode);
		userAccountHistory.setCurFreezeBal(newAcct.getFreezeBalance());
		userAccountHistory.setUserId(userAccount.getUserId());
		userAccountFreezeHistoryRepository.save(userAccountHistory);
		em.flush();
		return newAcct;
	}

	@Transactional
	@Override
	public UserAccount freezeUserRebateAccount(UserAccount userAccount,
											   BigDecimal amount, String addorsub, String ordercode)
			throws Exception {

		UserAccount olduserAccount = accountRepository.findUserAccountByUseridLock(userAccount.getUserId());

		/**账户先减去钱， 然后冻结账户增加钱*/
		if(addorsub.equalsIgnoreCase("0")){

			BigDecimal curRebateBal = userAccount.getRebateBalance().subtract(amount);
			BigDecimal freezeRebateBal = userAccount.getFreezerebateBalance().add(amount);

			olduserAccount.setFreezerebateBalance(freezeRebateBal);
			olduserAccount.setRebateBalance(curRebateBal);

		}else{

			BigDecimal curBal = userAccount.getRebateBalance().add(amount);
			BigDecimal freezeBal = userAccount.getFreezerebateBalance().subtract(amount);


			if(freezeBal.compareTo(BigDecimal.ZERO) < 0){
				throw new Exception("不能多解冻金额");
			}

			olduserAccount.setFreezerebateBalance(freezeBal);
			olduserAccount.setRebateBalance(curBal);

		}
		UserAccount newAcct = accountRepository.save(olduserAccount);

		UserRebateAccountFreezeHistory  userAccountHistory = new  UserRebateAccountFreezeHistory();
		userAccountHistory.setAddOrSub(addorsub);
		userAccountHistory.setAmount(amount);
		userAccountHistory.setCreateTime(new Date());
		userAccountHistory.setOrderCode(ordercode);
		userAccountHistory.setCurFreezeBal(newAcct.getFreezeBalance());
		userAccountHistory.setUserId(userAccount.getUserId());
		userRebateFreezeHistoryRepository.save(userAccountHistory);
		em.flush();
		return newAcct;
	}



	/**将用户的分润的钱扣除， 然后将用户的余额增加*/
	@Transactional
	@Override
	public UserAccount updateUserRebateAccount(UserAccount userAccount, BigDecimal amount, String ordercode) {

		UserAccount olduserAccount = accountRepository.findUserAccountByUseridLock(userAccount.getUserId());

		BigDecimal rebatebal = userAccount.getRebateBalance().subtract(amount);

		BigDecimal curBal  =   userAccount.getBalance().add(amount);
		olduserAccount.setRebateBalance(rebatebal);
		olduserAccount.setBalance(curBal);

		UserAccount newAcct = accountRepository.save(olduserAccount);

		UserBalanceHistory  balHistory = new  UserBalanceHistory();
		balHistory.setAddOrSub("0");
		balHistory.setOrderCode(ordercode);
		balHistory.setAmount(amount);
		balHistory.setCreateTime(new Date());
		balHistory.setCurBal(curBal);
		balHistory.setUserId(userAccount.getUserId());
		userBalanceRepository.save(balHistory);


		UserRebateHistory   rebateHistory = new UserRebateHistory();
		rebateHistory.setAddOrSub("2");
		rebateHistory.setOrderCode(ordercode);
		rebateHistory.setCreateTime(new Date());
		rebateHistory.setCurRebate(rebatebal);
		rebateHistory.setRebate(amount);
		rebateHistory.setUserId(userAccount.getUserId());
		userRebateHistoryRepository.save(rebateHistory);
		em.flush();
		return newAcct;
	}

	/***
	 * 判定是否存在
	 *
	 * */
	public UserBalanceHistory findUserBalByUidAndorsubAndOrCode(long userId,String  addorsub, String ordercode){

		return userBalanceRepository.findUserBalByUidAndorsubAndOrCode(userId, ordercode, addorsub);
	}
	@Transactional
	@Override
	public UserAccount updateUserAccount(UserAccount userAccount, BigDecimal amount,  String  addorsub, String ordercode) throws Exception{

		UserAccount olduserAccount = accountRepository.findUserAccountByUseridLock(userAccount.getUserId());
		UserBalanceHistory  balHistory =findUserBalByUidAndorsubAndOrCode(userAccount.getUserId(), addorsub, ordercode);
		if(balHistory!=null){
			log.info("重复入账问题出现请检查用户Id="+userAccount.getUserId()+";用户订单号="+ordercode);
			return olduserAccount;
		}
		BigDecimal curBal = BigDecimal.ZERO;
		if(addorsub.equalsIgnoreCase("0")){

			curBal = userAccount.getBalance().add(amount);

		}else{

			curBal = userAccount.getBalance().subtract(amount);

		}


		if(curBal.compareTo(BigDecimal.ZERO) < 0){
			throw new Exception("金额不能为负数 ");
		}



		olduserAccount.setBalance(curBal);
		UserAccount newAcct = accountRepository.save(olduserAccount);
		balHistory = new  UserBalanceHistory();
		balHistory.setAddOrSub(addorsub);
		balHistory.setOrderCode(ordercode);
		balHistory.setAmount(amount);
		balHistory.setCreateTime(new Date());
		balHistory.setCurBal(curBal);
		balHistory.setUserId(userAccount.getUserId());
		userBalanceRepository.save(balHistory);



		em.flush();

		return newAcct;
	}

	/**按ID查询用户的日。月。总 收入***/

	@Transactional
	@Override
	public Map<String, BigDecimal> findSumUserBalByUserId( long userid){
		Map<String, BigDecimal> map =new HashMap<String, BigDecimal>();
		Date dt=new Date();
		SimpleDateFormat matter1=new SimpleDateFormat("yyyy-MM-dd");
		String dayString =matter1.format(dt)+" 00:00:00";
		Date today=DateUtil.getYYMMHHMMSSDateFromStr(dayString);


		SimpleDateFormat matter2=new SimpleDateFormat("yyyy-MM");
		String monString =matter2.format(dt)+"-01 00:00:00";
		Date month=DateUtil.getYYMMHHMMSSDateFromStr(monString);


		map.put("daysum",userBalanceRepository.findSumUserBalByUserIdstats0(userid, today).subtract(userBalanceRepository.findSumUserBalByUserIdstats1(userid, today)));
		map.put("monsum",userBalanceRepository.findSumUserBalByUserIdstats0(userid, month).subtract(userBalanceRepository.findSumUserBalByUserIdstats1(userid, month)));
		map.put("allsum", userBalanceRepository.findSumUserBalByUserIdstats0(userid).subtract(userBalanceRepository.findSumUserBalByUserIdstats1(userid)));
		map.put("rebatebalance", accountRepository.findUserAccountByUserid(userid).getBalance());
		return map;
	}

	public List<Channel> getChannelList(long userId, long payType, long channelId,String amountMoney,String type) {
		return channelRateBusiness.findAllChannel(userId, payType, channelId,amountMoney,type);
	}

	/**
	 * 余额提现时更新用户账户信息
	 * @param userId
	 * @param amount 提现金额
	 * @param actualAmount 实际提现金额
	 * @param balance 余额 = 初始余额 - 提现金额
	 * @param addorsub 0加1减（0充值，1提现）
	 * @return
	 */
	@Override
	@Transactional
	public UserAccount updateAccount(String bankCard, long userId, BigDecimal amount, BigDecimal actualAmount, String orderCode, BigDecimal balance, String addorsub) throws ServiceException {
		//1、获取用户账户余额信息
		UserAccount oldUserAccount = accountRepository.getUserAccount(userId);
		if (oldUserAccount.getBalance().compareTo(amount) < 0) {
			throw new ServiceException("余额不足，无法提现！");
		}
		long id = oldUserAccount.getId();
		//提现后账户余额
		BigDecimal subtractBalance = oldUserAccount.getBalance().subtract(amount);
		//体现后账户冻结金额
		BigDecimal addFreezeBalance = oldUserAccount.getFreezeBalance().add(amount);
		oldUserAccount.setBalance(subtractBalance);
		oldUserAccount.setFreezeBalance(addFreezeBalance);
		//em.merge(oldUserAccount);
		//em.flush();

		accountRepository.updateAccount(userId, subtractBalance, addFreezeBalance);

		/* 2、保存账户历史记录表，用于在 我的-账单-提现 中查看历史提现记录 */
		UserBalanceHistory userBalanceHistory = new UserBalanceHistory();
		userBalanceHistory.setUserId(userId);
		userBalanceHistory.setAmount(subtractBalance);
		userBalanceHistory.setAddOrSub("1");//余额减少
		userBalanceHistory.setCurBal(amount);//提现金额
		userBalanceHistory.setOrderCode(orderCode);
		userBalanceHistory.setCreateTime(Calendar.getInstance().getTime());
		userBalanceRepository.save(userBalanceHistory);
		em.flush();

		/* 3、保存实际提现记录表 */
		UserAccountFreezeHistory userAccountFreezeHistory = new UserAccountFreezeHistory();
		userAccountFreezeHistory.setAddOrSub("1");
		userAccountFreezeHistory.setAmount(subtractBalance);
		userAccountFreezeHistory.setCreateTime(Calendar.getInstance().getTime());
		userAccountFreezeHistory.setCurFreezeBal(actualAmount);
		userAccountFreezeHistory.setOrderCode(orderCode);
		userAccountFreezeHistory.setUserId(oldUserAccount.getUserId());
		userAccountFreezeHistory.setBankCard(bankCard);
		userAccountFreezeHistoryRepository.save(userAccountFreezeHistory);
		em.flush();
		return oldUserAccount;
	}


	@Transactional
	@Override
	public UserAccount withdrawFreeAccount(long userid, BigDecimal amount, String ordercode)
	{

//		User user = userRepository.findUserByPhone(phone);
		UserAccount olduserAccount = accountRepository.findUserAccountByUseridLock(userid);

		if(olduserAccount.getBalance().compareTo(amount) < 0){

			return null;

		}else{

			/**先冻结提现的钱*/
			BigDecimal curBal = olduserAccount.getBalance().subtract(amount);
			BigDecimal freezeBal = olduserAccount.getFreezeBalance().add(amount);

			olduserAccount.setFreezeBalance(freezeBal);
			olduserAccount.setBalance(curBal);

		}

		UserAccount newAcct = accountRepository.save(olduserAccount);

		UserAccountFreezeHistory  userAccountHistory = new  UserAccountFreezeHistory();
		userAccountHistory.setAddOrSub("0");
		userAccountHistory.setAmount(amount);
		userAccountHistory.setCreateTime(new Date());
		userAccountHistory.setOrderCode(ordercode);
		userAccountHistory.setCurFreezeBal(newAcct.getFreezeBalance());
		userAccountHistory.setUserId(newAcct.getUserId());
		userAccountFreezeHistoryRepository.save(userAccountHistory);
		em.flush();
		return newAcct;
	}

	@Transactional
	@Override
	public UserAccount rebateFreezeAccount(long userid, BigDecimal amount,
										   String ordercode) {

//		User user = userRepository.findUserByPhone(phone);
		UserAccount olduserAccount = accountRepository.findUserAccountByUseridLock(userid);

		if(olduserAccount.getRebateBalance().compareTo(amount) < 0){

			return null;

		}else{

			/**先冻结提现的钱*/
			BigDecimal curRebateBal = olduserAccount.getRebateBalance().subtract(amount);
			BigDecimal freezeRebateBal = olduserAccount.getFreezerebateBalance().add(amount);

			olduserAccount.setFreezerebateBalance(freezeRebateBal);
			olduserAccount.setRebateBalance(curRebateBal);

		}

		UserAccount newAcct = accountRepository.save(olduserAccount);



		UserRebateAccountFreezeHistory  userAccountHistory = new  UserRebateAccountFreezeHistory();
		userAccountHistory.setAddOrSub("0");
		userAccountHistory.setAmount(amount);
		userAccountHistory.setCreateTime(new Date());
		userAccountHistory.setOrderCode(ordercode);
		userAccountHistory.setCurFreezeBal(newAcct.getFreezeBalance());
		userAccountHistory.setUserId(newAcct.getUserId());
		userRebateFreezeHistoryRepository.save(userAccountHistory);
		em.flush();
		return newAcct;
	}


	@Transactional
	public UserAccount addUserAccount(UserAccount userAccount,BigDecimal amount){
		UserAccount olduserAccount = accountRepository.findUserAccountByUseridLock(userAccount.getUserId());
		if(olduserAccount != null){

		}
		BigDecimal rebate = olduserAccount.getRebateBalance();
		BigDecimal re = olduserAccount.getSumRebateBalance();
		int amounts = amount.compareTo(BigDecimal.ZERO);
		if(amounts < 0){

		}
		BigDecimal ac = rebate.add(amount);
		BigDecimal sum = re.add(amount);
		olduserAccount.setSumRebateBalance(sum);//分润累计金额
		olduserAccount.setRebateBalance(ac);//分润余额
		UserAccount newAcct = accountRepository.save(olduserAccount);
		em.flush();
		return newAcct;
	}

	/**
	 * 分润提现到余额
	 * @param userId
	 * @param rebateAmount 提现分润金额
	 * @param rebateBalance 提现前分润余额
	 * @return
	 */
	@Override
	@Transactional
	public UserAccount rebateWithdraw(long userId, BigDecimal rebateAmount, BigDecimal rebateBalance) throws ServiceException {
		/* 1、生成订单号 */
		Random rand = new Random();
		int randNum = rand.nextInt(9999)+10000;
		String orderCode = DateUtil.getyyyyMMddHHmmssSSSDateFormat(Calendar.getInstance().getTime()) + randNum;

		/* 2、获取用户账户信息 */
		UserAccount userAccountByUserid = accountRepository.findUserAccountByUserid(userId);
		if (userAccountByUserid == null) {
			throw new ServiceException("未获取用户账户信息！");
		}

		//余额
		BigDecimal existBalance = userAccountByUserid.getBalance();
		//分润余额
		BigDecimal existRebateBalance = userAccountByUserid.getRebateBalance();
		//冻结分润金额
		BigDecimal existFreezerebateBalance = userAccountByUserid.getFreezerebateBalance();

		if (rebateBalance.compareTo(existRebateBalance) != 0) {
			throw new ServiceException("提现失败！");
		}
		if (rebateAmount.compareTo(existRebateBalance) > 0) {
			throw new ServiceException("提现失败！");
		}

		//分润提现金额提现到账户余额
		BigDecimal newBalance = existBalance.add(rebateAmount);
		//分入余额 = 分润余额 - 分润提现金额
		BigDecimal newRebateBalance = existRebateBalance.subtract(rebateAmount);
		BigDecimal newFreezerebateBalance = existFreezerebateBalance.add(rebateAmount);

		userAccountByUserid.setBalance(newBalance);
		userAccountByUserid.setRebateBalance(newRebateBalance);
		userAccountByUserid.setFreezerebateBalance(newFreezerebateBalance);

		/* 3、更新用户账户信息表 */
		int result = accountRepository.updateRebateBalance(userId, newRebateBalance, newFreezerebateBalance, newBalance);
		if (result != 1) {
			throw new ServiceException("提现失败！");
		}
		/* 4、更新t_user_account_freeze_history表 */
		UserAccountFreezeHistory userAccountFreezeHistory = new UserAccountFreezeHistory();
		userAccountFreezeHistory.setUserId(userId);
		userAccountFreezeHistory.setAmount(newBalance);
		userAccountFreezeHistory.setAddOrSub("0");//0加1减
		userAccountFreezeHistory.setCurFreezeBal(rebateAmount);//进账金额
		userAccountFreezeHistory.setOrderCode(orderCode);
		userAccountFreezeHistory.setCreateTime(Calendar.getInstance().getTime());
		userAccountFreezeHistoryRepository.save(userAccountFreezeHistory);
		em.flush();

		/* 5、更新分润历史记录表 */
		UserRebateAccountFreezeHistory rebateFreezeHistory = new UserRebateAccountFreezeHistory();
		rebateFreezeHistory.setAddOrSub("1");//分润提现
		rebateFreezeHistory.setAmount(newRebateBalance);
		rebateFreezeHistory.setCurFreezeBal(rebateAmount);
		rebateFreezeHistory.setUserId(userId);
		rebateFreezeHistory.setOrderCode(orderCode);
		rebateFreezeHistory.setCreateTime(Calendar.getInstance().getTime());
		userRebateFreezeHistoryRepository.save(rebateFreezeHistory);
		em.flush();
		return userAccountByUserid;
	}

	@Override
	public Page<UserBalanceHistory> queryAccountHistory(long userId, Pageable pageable) throws ServiceException {
		Page<UserBalanceHistory> userBalanceHistoriePage = userBalanceRepository.queryAccountHistory(userId, pageable);
		return userBalanceHistoriePage;
	}

	@Override
	public Page<UserRebateAccountFreezeHistory> queryRebatePage(long userId, Pageable pageable) throws ServiceException {
		Page<UserRebateAccountFreezeHistory> page = userRebateFreezeHistoryRepository.queryRebatePage(userId, pageable);
		return page;
	}

	@Override
	@Transactional
	public UserAccount refundBalannce(long userId, String orderCode) throws ServiceException {
		UserAccount userAccount = accountRepository.findUserAccountByUserid(userId);
		BigDecimal balance = userAccount.getBalance();
		BigDecimal freezeBalance = userAccount.getFreezeBalance();

		UserBalanceHistory userBalanceHistory = userBalanceRepository.getUserBalanceHistoryByOrderCode(orderCode);
		if (userBalanceHistory != null) {
			BigDecimal curBal = userBalanceHistory.getCurBal();
			BigDecimal newBalance = balance.add(curBal);
			BigDecimal newFreezeBalance = freezeBalance.subtract(curBal);
			userAccount.setBalance(newBalance);
			userAccount.setFreezeBalance(newFreezeBalance);
			accountRepository.uodateByUserId(userId, newBalance, newFreezeBalance);
			userBalanceRepository.deleteByOrderCode(orderCode);
			userAccountFreezeHistoryRepository.deleteByOrderCode(orderCode);
		}
		return userAccount;
	}




}
